package com.fowo.api.syncLingxingApi.service.syncImpl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.fowo.api.entity.Product;
import com.fowo.api.syncLingxingApi.entity.TmpSyncLingxingToProductInfo;
import com.fowo.api.service.impl.ProductServiceImpl;
import com.fowo.api.syncLingxingApi.service.SyncLxApiBaseService;
import com.fowo.api.syncLingxingApi.service.impl.TmpSyncLingxingToProductInfoServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
@DS("ds24")
public class SyncLxBatchProductInfoServiceImpl
        extends SyncLxApiBaseService <TmpSyncLingxingToProductInfo, Product>  {
    private final static String LX_API_URL_KEY = "batchGetProductInfo";
    private final static int MAX_LEN = 100;

    @Resource
    private TmpSyncLingxingToProductInfoServiceImpl tmpSyncLingxingToProductInfoService;

    @Resource
    private ProductServiceImpl productService;

    public SyncLxBatchProductInfoServiceImpl() {
        super(LX_API_URL_KEY, MAX_LEN);
    }

    @Override
    protected void beforeLoop() {
        this.totalNum = productService.count();
        tmpSyncLingxingToProductInfoService.deleteAll();
    }

    @Override
    protected JSONObject pullLingxingData(long offset, long length, JSONObject params) {
        this.logInfo("发起请求数据：" + this.lxApiUrl);
        if (params == null || params.isEmpty()) {
            params = new JSONObject();
            params.put("skus", tmpSyncLingxingToProductInfoService.getAllSku(offset, length));
        }
        else {
            if (params.containsKey("skus"))
                this.totalNum = params.getJSONArray("skus").size();

            else if (params.containsKey("productIds"))
                this.totalNum = params.getJSONArray("productIds").size();

            else
                this.totalNum = 0;
        }

        List<Integer> productIds = new ArrayList<>();
        List<String> skus = new ArrayList<>();

        if (params.containsKey("productIds"))
            productIds = params.getJSONArray("productIds").toJavaList(Integer.class);
        if (params.containsKey("skus"))
            skus = params.getJSONArray("skus").toJavaList(String.class);

        Map<String, Object> reqParams = new HashMap<>();
        reqParams.put("productIds", productIds);
        reqParams.put("skus", skus);

        JSONObject results = null;
        while (true) {
//            results == null
//            results.getInteger("code") == 500
//            !productIds.isEmpty()
//            !skus.isEmpty()

            results = this.tryRequestLingxingApi(reqParams);
//            log.info(results.toJSONString());
            /*
             * 例子：错误信息如下 error_details
             *  - 产品ID 1700222444618457090 未找到数据 [请求码:806E84]
             *  - 产品SKU xxx
             */
            if (results != null && results.getInteger("code") != 0) {
                String errDetails = results.getString("error_details");

                List<String> rltList = List.of(errDetails.split(" "));
                if (rltList.size() > 1) {
                    if (rltList.get(0).trim().equals("产品ID")) {
                        productIds.remove(Integer.valueOf(rltList.get(1)));
                        if (productIds.isEmpty()) {
                            this.logInfo("请求产品ID列表为空。");
                            break;
                        }
                    }
                    else if (rltList.get(0).trim().equals("产品SKU")) {
                        skus.remove(rltList.get(1));
                        if (skus.isEmpty()) {
                            this.logInfo("请求sku列表为空。");
                            break;
                        }
                    }
                    else {
                        this.logInfo("处理错误异常。");
                        break;
                    }
                } else {
                    this.logInfo("请求处理错误不在处理范围内: " + results);
                    break;
                }
            } else {
                break;
            }
        }

        return results;
    }

    @Override
    protected boolean loopCond() {
        return super.loopCond();
    }

    @Override
    protected boolean cmpNewAndOldEqualCond(TmpSyncLingxingToProductInfo newOne, Product oldOne) {
        if (newOne == null || oldOne == null)
            return false;

        return newOne.getSku().equals(oldOne.getSku());
    }

    @Override
    protected TmpSyncLingxingToProductInfo cmpNewAndOldInsertProc(TmpSyncLingxingToProductInfo newOne) {
        newOne.setFlag(2);
        return newOne;
    }

    @Override
    protected TmpSyncLingxingToProductInfo cmpNewAndOldUpdateProc(TmpSyncLingxingToProductInfo newOne, Product oldOne) {
        newOne.setFlag(1);
        return newOne;
    }

    @Override
    protected boolean cmpNewAndOldUpdateCond(TmpSyncLingxingToProductInfo newOne, Product oldOne) {
        if (newOne == null || oldOne == null)
            return false;
        return true;
    }


    @Override
    protected void saveTempToFormal() {
//        tmpSyncLingxingToProductInfoService.updateToProducts(this.data_version);
        tmpSyncLingxingToProductInfoService.updateProductInfo(this.data_version);
        tmpSyncLingxingToProductInfoService.updateCustomsPrice(this.data_version);
        tmpSyncLingxingToProductInfoService.insertCustomsPrice(this.data_version);
    }

    @Override
    protected List<TmpSyncLingxingToProductInfo> jsonDumpsResult(JSONArray jsonArray) {
        List<TmpSyncLingxingToProductInfo> tmpSyncLingxingToProductInfoList = new ArrayList<>();

        for (Object obj: jsonArray) {
            JSONObject j = (JSONObject) obj;
            TmpSyncLingxingToProductInfo newObj = new TmpSyncLingxingToProductInfo();

            newObj.setId(j.getInteger("id"));
            newObj.setSku(j.getString("sku"));
            newObj.setPicUrl(j.getString("pic_url"));
            newObj.setProductName(j.getString("product_name"));
            newObj.setPictureList(j.getString("picture_list"));
            newObj.setPermissionUserInfo(j.getString("permission_user_info"));
            newObj.setModel(j.getString("model"));
            newObj.setUnit(j.getString("unit"));
            newObj.setStatus(j.getInteger("status"));
            newObj.setCid(j.getInteger("cid"));
            newObj.setBid(j.getInteger("bid"));
            newObj.setProductDeveloper(j.getString("product_developer"));
            newObj.setProductDeveloperUid(j.getInteger("product_developer_uid"));
            newObj.setGlobalTag(j.getString("global_tags"));
            newObj.setDescription(j.getString("description"));
            newObj.setIsCombo(j.getInteger("is_combo"));
            newObj.setBrandName(j.getString("brand_name"));
            newObj.setCategoryName(j.getString("category_name"));
            newObj.setAttachmentId(j.getString("attachment_id"));
            newObj.setSpecialAttr(j.getString("special_attr"));
            newObj.setCurrency(j.getString("currency"));
            newObj.setCgOptUsername(j.getString("cg_opt_username"));
            newObj.setCgDelivery(j.getInteger("cg_delivery"));
            newObj.setCgPrice(j.getFloat("cg_price"));
            newObj.setPurchaseRemark(j.getString("purchase_remark"));
            newObj.setCgProductMaterial(j.getString("cg_product_material"));
            newObj.setCgProductLength(j.getFloat("cg_product_length"));
            newObj.setCgProductWidth(j.getFloat("cg_product_width"));
            newObj.setCgProductHeight(j.getFloat("cg_product_height"));
            newObj.setCgPackageHeight(j.getFloat("cg_package_height"));
            newObj.setCgPackageWidth(j.getFloat("cg_package_width"));
            newObj.setCgPackageLenght(j.getFloat("cg_package_length"));
            newObj.setCgBoxLenght(j.getFloat("cg_box_length"));
            newObj.setCgBoxWidth(j.getFloat("cg_box_width"));
            newObj.setCgBoxHeight(j.getFloat("cg_box_height"));
            newObj.setCgProductNetWeight(j.getFloat("cg_product_net_weight"));
            newObj.setCgProductGrossWeight(j.getFloat("cg_product_gross_weight"));
            newObj.setCgBoxWeight(j.getFloat("cg_box_weight"));
            newObj.setCgBoxPcs(j.getInteger("cg_box_pcs"));
            newObj.setBgCustomsExportName(j.getString("bg_customs_export_name"));
            newObj.setBgCustomsImportName(j.getString("bg_customs_import_name"));
            newObj.setBgCustomsImportPrice(j.getFloat("bg_customs_import_price"));
            newObj.setBgExportHsCode(j.getString("bg_export_hs_code"));
            newObj.setBgImortHsCode(j.getString("bg_import_hs_code"));
            newObj.setBgTaxRate(j.getFloat("bg_tax_rate"));
            newObj.setQcStandard(j.getString("qc_standard"));
            newObj.setSupplierQuote(j.getString("supplier_quote"));
            newObj.setComboProductList(j.getString("combo_product_list"));
            newObj.setProductLogisticsRelation(j.getString("product_logistics_relation"));
            newObj.setDeclaration(j.getString("declaration"));
            newObj.setClearance(j.getString("clearance"));

            newObj.setVersion(this.data_version);
            tmpSyncLingxingToProductInfoList.add(newObj);
        }

        return tmpSyncLingxingToProductInfoList;
    }

    @Override
    protected List<Product> getOldData(List<TmpSyncLingxingToProductInfo> newObjects) {
        return tmpSyncLingxingToProductInfoService.getBySku(newObjects);
    }

    @Override
    protected void saveData2TmpTb(List<TmpSyncLingxingToProductInfo> results) {
        log.info("Saved results size is " + results.size() + ".");
        tmpSyncLingxingToProductInfoService.saveBatch(results);
    }


}
